package cn.cubix.flow.controller.userprms;

import cn.cubix.flow.entity.WfPrms;
import cn.cubix.flow.entity.WfPrmsRole;
import cn.cubix.flow.entity.WfRole;
import cn.cubix.flow.mapper.WfPrmsRoleMapper;
import cn.cubix.flow.service.WfPrmsService;
import cn.cubix.flow.service.WfRoleService;
import cn.cubix.flow.util.Result;
import cn.cubix.flow.entity.WfUser;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@RestController
@RequestMapping("/api/userprms/role")
@RequiredArgsConstructor(onConstructor=@__({@Autowired,@Lazy}))
public class WfRoleApi {

    private final WfRoleService wfRoleService;
    private final WfPrmsRoleMapper wfPrmsRoleMapper;
    private final WfPrmsService wfPrmsService;

    /** 分页查询系统角色 */
    @PostMapping("/page")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_PAGE')")
    public Object page(@RequestBody JSONObject body){
        long current = 1L, size = 10L, total = 0L;
        if(body.containsKey("page")){
            JSONObject page = body.getJSONObject("page");
            current = page.getLong("current",current);
            size = page.getLong("size",size);
        }
        LambdaQueryWrapper<WfRole> queryWrapper = new LambdaQueryWrapper<>();
        IPage<WfRole> page = wfRoleService.page(new Page<>(current,size),queryWrapper);
        return Result.SUCCESS(page.getRecords(),"查询成功").setPage(current,size,page.getTotal());
    }

    /** 新建系统角色 */
    @PostMapping("/create")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_CREATE')")
    public Object create(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("保存失败");
        if(body.containsKey("record")){
            JSONObject record = body.getJSONObject("record");
            WfRole wfRole = record.toBean(WfRole.class);
            boolean saveResult = wfRoleService.save(wfRole);
            if(saveResult){
                result.toSuccess().setMessage("保存成功");
            }
        }
        return result;
    }

    /** 删除系统角色 */
    @PostMapping("/delete")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_DELETE')")
    public Object delete(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("删除失败");
        if(body.containsKey("params")){
            JSONObject params = body.getJSONObject("params");
            Collection<String> ids = Stream.of(params.getStr("id","null").split(",")).collect(Collectors.toList());
            boolean removeResult = wfRoleService.removeByIds(ids);
            if(removeResult){
                result.toSuccess().setMessage("删除成功");
            }
        }
        return result;
    }

    /** 获取系统角色 */
    @GetMapping("/get/{id}")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_GET')")
    public Object get(@PathVariable("id")String id){
        Result<Object> result = Result.FAILURE().setMessage("查询失败");
        WfRole wfRole = wfRoleService.getById(id);
        if(wfRole!=null){
            result.toSuccess().setRecord(wfRole).setMessage("查询成功");
        }
        return result;
    }

    /** 更新系统角色 */
    @PostMapping("/update")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_UPDATE')")
    public Object update(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("更新失败");
        if(body.containsKey("record")){
            JSONObject record = body.getJSONObject("record");
            WfRole wfRole = record.toBean(WfRole.class);
            boolean updateResult = wfRoleService.updateById(wfRole);
            if(updateResult){
                result.toSuccess().setMessage("更新成功");
            }
        }
        return result;
    }

    /* 以下是角色权限部分 *************************************************************************************************/

    /** 分页查询已分配给系统角色的系统权限 */
    @PostMapping("/prms/page")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_PRMS_PAGE')")
    public Object prmsPage(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("权限查询失败");
        long current = 1L, size = 10L, total = 0L;
        if(body.containsKey("page")){
            JSONObject page = body.getJSONObject("page");
            current = page.getLong("current",current);
            size = page.getLong("size",size);
        }
        if(body.containsKey("params")){
            JSONObject params = body.getJSONObject("params");
            String roleId = params.getStr("roleId","null");
            IPage<WfPrmsRole> page = wfPrmsRoleMapper.pageByRoleId(new Page<>(current,size),roleId,new LambdaQueryWrapper<>());
            List<JSONObject> record = page.getRecords().stream().map(
                    wfPrmsUser -> new JSONObject()
                            .set("id",wfPrmsUser.getId())
                            .set("prmsId",wfPrmsUser.getPrmsId())
                            .set("roleId",wfPrmsUser.getRoleId())
                            .set("disabled",wfPrmsUser.getDisabled())
                            .set("prmsCode",wfPrmsUser.getPrms().getCode())
                            .set("prmsName",wfPrmsUser.getPrms().getName())
            ).collect(Collectors.toList());
            result.toSuccess().setMessage("权限查询成功").setRecord(record).setPage(current,size,page.getTotal());
        }
        return result;
    }

    /** 分页查询未分配给系统角色的系统权限 */
    @PostMapping("/prms/available")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_PRMS_AVAILABLE')")
    public Object prmsAvailable(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("权限查询失败");
        long current = 1L, size = 10L, total = 0L;
        if(body.containsKey("page")){
            JSONObject page = body.getJSONObject("page");
            current = page.getLong("current",current);
            size = page.getLong("size",size);
        }
        if(body.containsKey("params")){
            JSONObject params = body.getJSONObject("params");
            String search = params.getStr("_search");
            String roleId = params.getStr("roleId","null");
            LambdaQueryWrapper<WfPrms> queryWrapper = new LambdaQueryWrapper<>();
            if(StrUtil.isNotEmpty(search)){
                queryWrapper.like(WfPrms::getName,search);
            }
            IPage<WfPrms> page = wfPrmsRoleMapper.pagePrmsAvailable(new Page<>(current,size),roleId,queryWrapper);
            List<JSONObject> record = page.getRecords().stream().map(
                    wfRole -> new JSONObject()
                            .set("id",wfRole.getId())
                            .set("code",wfRole.getCode())
                            .set("name",wfRole.getName())
            ).collect(Collectors.toList());
            result.toSuccess().setMessage("权限查询成功").setRecord(record).setPage(current,size,page.getTotal());
        }
        return result;
    }

    /** 收回分配给系统角色的系统权限 */
    @PostMapping("/prms/regain")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_PRMS_REGAIN')")
    public Object prmsRegain(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("权限收回失败");
        if(body.containsKey("params")) {
            JSONObject params = body.getJSONObject("params");
            Set<String> idSet = params.getJSONArray("id")
                    .stream().map(StrUtil::toString).collect(Collectors.toSet());
            int deleted = wfPrmsRoleMapper.deleteBatchIds(idSet);
            if(deleted>=0){
                result.toSuccess().setMessage(String.format("成功收回%s个权限",deleted));
            }
        }
        return result;
    }

    /** 分配系统权限给系统角色 */
    @PostMapping("/prms/allocate")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_PRMS_ALLOCATE')")
    public Object prmsAllocate(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("权限分配失败");
        if(body.containsKey("params")) {
            JSONObject params = body.getJSONObject("params");
            String roleId  = params.getStr("roleId");
            Set<String> prmsIdSet = params.getJSONArray("prmsId")
                    .stream().map(StrUtil::toString).collect(Collectors.toSet());

            WfRole role = wfRoleService.getById(roleId);
            List<WfPrms> prmsList = wfPrmsService.listByIds(prmsIdSet);

            if(role!=null&&!prmsList.isEmpty()){
                prmsList.forEach(prms->{
                    WfPrmsRole wfPrmsUser = new WfPrmsRole();
                    wfPrmsUser.setRoleId(role.getId());
                    wfPrmsUser.setPrmsId(prms.getId());
                    wfPrmsUser.setDisabled(false);
                    wfPrmsRoleMapper.insert(wfPrmsUser);
                });
                result.toSuccess().setMessage("权限分配成功");
            }
        }
        return result;
    }

    /** 禁用/启用分配给系统角色的系统权限 */
    @PostMapping("/prms/disable")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_PRMS_DISABLE')")
    public Object prmsDisable(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("权限配置失败");
        if(body.containsKey("params")) {
            JSONObject params = body.getJSONObject("params");
            boolean disabled = params.getBool("disabled");
            Set<String> idSet = params.getJSONArray("id")
                    .stream().map(StrUtil::toString).collect(Collectors.toSet());
            WfPrmsRole entity = new WfPrmsRole();
            entity.setDisabled(disabled);
            int count = wfPrmsRoleMapper.update(entity,new LambdaQueryWrapper<WfPrmsRole>().in(WfPrmsRole::getId,idSet));
            if(count>=0){
                result.toSuccess().setMessage(String.format("成功%s用%s个权限",disabled?"禁":"启",count));
            }
        }
        return result;
    }

    /*  *************************************************************************************************/

    /** 分配角色到用户 */
    @PostMapping("/alloc/user")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_ALLOC_USER')")
    public Object allocUser(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("分配失败");
        if(body.containsKey("params")){
            JSONObject params = body.getJSONObject("params");
            String roleid = params.getStr("roleid","null");
            List<String> userids = Stream.of(params.getStr("userid","null")
                    .split(","))
                    .filter(id->(!"null".equalsIgnoreCase(id)&&!"".equals(id)))
                    .collect(Collectors.toList());
            wfRoleService.allocUser(roleid,userids);
            result.toSuccess().setMessage("分配成功");
        }
        return result;
    }

    /** 已分配角色的用户 */
    @PostMapping("/alced/user")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_ALCED_USER')")
    public Object alcedUser(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("查询失败");
        if(body.containsKey("params")) {
            JSONObject params = body.getJSONObject("params");
            String roleid = params.getStr("roleid","null");
            List<WfUser> records = wfRoleService.alcedUser(roleid);
            result.toSuccess().setRecord(records).setMessage("查询成功");
        }
        return result;
    }

    /** 分配权限到角色 */
    @PostMapping("/alloc/prms")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_ALLOC_PRMS')")
    public Object allocPrms(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("分配失败");
        if(body.containsKey("params")){
            JSONObject params = body.getJSONObject("params");
            String roleid = params.getStr("roleid","null");
            List<String> prmsids = Stream.of(params.getStr("prmsid","null")
                            .split(","))
                    .filter(id->(!"null".equalsIgnoreCase(id)&&!"".equals(id)))
                    .collect(Collectors.toList());
            wfRoleService.allocPrms(roleid,prmsids);
            result.toSuccess().setMessage("分配成功");
        }
        return result;
    }

    /** 已分配角色的权限 */
    @PostMapping("/alced/prms")
    @PreAuthorize("hasAnyAuthority('ADMIN','API_USERPRMS_ROLE_ALCED_PRMS')")
    public Object alcedPrms(@RequestBody JSONObject body){
        Result<Object> result = Result.FAILURE().setMessage("查询失败");
        if(body.containsKey("params")) {
            JSONObject params = body.getJSONObject("params");
            String roleid = params.getStr("roleid","null");
            List<WfPrms> records = wfRoleService.alcedPrms(roleid);
            result.toSuccess().setRecord(records).setMessage("查询成功");
        }
        return result;
    }

}
